package com.linrui.user.service.impl;

import com.linrui.basic.constants.WxConstants;
import com.linrui.basic.utils.AjaxResult;
import com.linrui.basic.utils.MD5Utils;
import com.linrui.user.domain.Logininfo;
import com.linrui.user.dto.AccountLoginDTO;
import com.linrui.user.dto.SmsLoginDto;
import com.linrui.user.mapper.LogininfoMapper;
import com.linrui.user.service.ILogininfoService;
import com.linrui.basic.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author linrui
 * @since 2022-11-14
 */
@Service
public class LogininfoServiceImpl extends BaseServiceImpl<Logininfo> implements ILogininfoService {
    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 账号登录
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public AjaxResult accountLogin(AccountLoginDTO dto) {
        String username = dto.getUsername();
        String password = dto.getPassword();
        Integer type = dto.getType();
        // 1 参数校验
        // 1.1 参数非空校验
        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password) && type == null){
            //throw new RuntimeException("参数错误!请检查后重新登录");
            return AjaxResult.me().setSuccess(false).setMessage("参数错误!请检查后重新登录");
        }

        // 2 根据username查询登录信息是否存在  匹配username phone email
        Logininfo logininfo = logininfoMapper.findLogininfoByUsername(dto);
        if(Objects.isNull(logininfo)){
            //throw new RuntimeException("用户名或密码错误!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("用户名或密码错误!请检查后重新登录!");
        }
        if(logininfo.getDisable() == 0){
            //throw new RuntimeException("该用户已被禁用!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("该用户已被禁用!请检查后重新登录!");
        }

        // 3 比对密码是否一致
        // 要先将前端传过来的明文密码，加密加盐以后，才可以和数据库的密码字段做比对
        password = MD5Utils.encrypByMd5("123"+logininfo.getSalt()+password);
        if(!password.equals(logininfo.getPassword())){
            return AjaxResult.me().setSuccess(false).setMessage("用户名或密码错误!请检查后重新登录!");
        }

        // 4 如果登录成功，就需要将用户信息存入redis  key-随机字符串  value-当前登录用户信息 设置30分钟的过期时间
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);

        // 5 将token和登录信息都返回给前端
        Map<String,Object> result = new HashMap<>();
        result.put("token", token);
        logininfo.setPassword("");
        logininfo.setSalt("");
        result.put("loginInfo", logininfo);

        return AjaxResult.me().setResult(result);
    }

    @Override
    public AjaxResult smsLogin(SmsLoginDto dto) {
        String mobile = dto.getMobile();
        String sms = dto.getSmsCode();
        Integer type = dto.getType();

        if(StringUtils.isEmpty(mobile) || StringUtils.isEmpty(sms) && type == null){
            //throw new RuntimeException("参数错误!请检查后重新登录");
            return AjaxResult.me().setSuccess(false).setMessage("参数错误!请检查后重新登录");
        }
        //根据mobile查询登录信息是否存在  匹配username phone email
        Logininfo logininfo = logininfoMapper.findUserByMobile(mobile);
        if(Objects.isNull(logininfo)){
            //throw new RuntimeException("用户名或密码错误!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("用户不存在");
        }
        if(logininfo.getDisable() == 0){
            //throw new RuntimeException("该用户已被禁用!请检查后重新登录!");
            return AjaxResult.me().setSuccess(false).setMessage("该用户已被禁用!请检查后重新登录!");
        }
        // 2 校验手机验证码是否正确(从redis取出之前的)
        String redisfromsms = (String) redisTemplate.opsForValue().get("login_sms_code" + mobile);
        if (StringUtils.isEmpty(redisfromsms)) {
            throw new RuntimeException("，请重新发送");
        }
        String loginSms = redisfromsms.split(":")[0];
        if (sms.equalsIgnoreCase(loginSms)) {
            throw new RuntimeException("验证码错误");
        }
        // 4 免密登录
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set("token", token, 24, TimeUnit.HOURS);
        // 5 将token和登录信息都返回给前端
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        logininfo.setPassword("");
        logininfo.setSalt("");
        map.put("logininfo", logininfo);
        return AjaxResult.me().setResult(map);
    }


}
